﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dzzzr;
using Nightwish.Controls.Tree;

namespace Dzzzr
{
	/// <summary>
	/// Manage teams tree
	/// </summary>
	public class TeamBrowserModel : ITreeModel
	{
		/// <summary>
		/// Associated teams
		/// </summary>
		List<Team> Teams = new List<Team>(2);
		
		/// <summary>
		/// Init object
		/// </summary>
		/// <param name="teams"></param>
		public void Init(IEnumerable<Team> teams)
		{
			Teams.Clear();
			Teams.AddRange(teams);
		}

		/// <summary>
		/// Return child elements
		/// </summary>
		/// <param name="treePath"></param>
		/// <returns></returns>
		public System.Collections.IEnumerable GetChildren(TreePath treePath)
		{
			if (treePath.IsEmpty())
			{
				// root items
				foreach (Team team in Teams)
				{
					yield return team;
				}
			}
			else
			{
				// children items
				if (treePath.LastNode is Team)
				{
					List<object> items = new List<object>(10);
					Team team = (Team)treePath.LastNode;
					foreach (User user in (from u in team.Users orderby u.Name select u))
						items.Add(user);
					foreach (Game game in (from g in team.Games orderby g.CreationDate select g))
						items.Add(game);
					foreach (object item in items)
					{
						yield return item;
					}
				}
				else if (treePath.LastNode is Game)
				{
					Game game = (Game)treePath.LastNode;
					var parentEntities = from ge in game.GameEntities where ge.ParentGameEntityID == null orderby ge.Entity.EntityTypeID, ge.Entity.Name select ge;
					foreach (GameEntity gameEntity in parentEntities)
					{
						yield return gameEntity;
					}
				}
				else if (treePath.LastNode is GameEntity)
				{
					GameEntity gameEntry = (GameEntity)treePath.LastNode;
					foreach (GameEntity gameEntity in (from ge in gameEntry.GameEntities orderby ge.Entity.EntityTypeID, ge.Entity.Name select ge))
					{
						yield return gameEntity;
					}
				}
			}
		}

		/// <summary>
		/// Check child items present
		/// </summary>
		/// <param name="treePath"></param>
		/// <returns></returns>
		public bool IsLeaf(TreePath treePath)
		{
			if (treePath.LastNode is Team)
			{
				Team team = (Team)treePath.LastNode;
				return team.Games.Count == 0 && team.Users.Count == 0;
			}
			else if (treePath.LastNode is User)
				return true;
			else if (treePath.LastNode is Game)
			{
				Game game = (Game)treePath.LastNode;
				var parentEntities = from ge in game.GameEntities where ge.ParentGameEntityID == null select ge;
				return parentEntities.Count() == 0;
			}
			else if (treePath.LastNode is GameEntity)
			{
				GameEntity gameEntry = (GameEntity)treePath.LastNode;
				return gameEntry.GameEntities.Count == 0;
			}
			else if (treePath.LastNode is Entity)
			{
				return true;
			}
			return true;
		}

		#region Events

		/// <summary>
		/// Event
		/// </summary>
		public event EventHandler<TreeModelEventArgs> NodesChanged;

		/// <summary>
		/// Event
		/// </summary>
		public event EventHandler<TreeModelEventArgs> NodesInserted;

		/// <summary>
		/// Event
		/// </summary>
		public event EventHandler<TreeModelEventArgs> NodesRemoved;

		/// <summary>
		/// Event
		/// </summary>
		public event EventHandler<TreePathEventArgs> StructureChanged;

		/// <summary>
		/// Fire event
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		public void FireNodesChanged(object sender, TreeModelEventArgs e)
		{
			if (NodesChanged != null)
				NodesChanged(sender, e);
		}

		/// <summary>
		/// Fire event
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		public void FireNodesInserted(object sender, TreeModelEventArgs e)
		{
			if (NodesInserted != null)
				NodesInserted(sender, e);
		}

		/// <summary>
		/// Fire event
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		public void FireNodesRemoved(object sender, TreeModelEventArgs e)
		{
			if (NodesRemoved != null)
				NodesRemoved(sender, e);
		}

		/// <summary>
		/// Fire event
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		public void FireStructureChanged(object sender, TreePathEventArgs e)
		{
			if (StructureChanged != null)
				StructureChanged(sender, e);
		}
		#endregion
	}
}
